package triangle.reader;

import java.io.File;

/**
 * This file is part of Rodney Ryan's submission of
 * his solution to the "Triangle Puzzle".
 * <p/>
 * This class uses a ReadingStrategy to return the
 * lines of a file in reverse order.
 *
 * rodney@rodneyryan.com
 */
public class BackwardsFileReader {

    private static final int MEGABYTE = 1048576;

    private boolean readingAllAtOnce;
    private ReadingStrategy readingStrategy;

    public BackwardsFileReader(String fileName, int allAtOnceSizeLimit_MB) {
        super();
        readingAllAtOnce = false;

        File file = new File(fileName);
        readingStrategy = createReadingStrategy(file.length(), allAtOnceSizeLimit_MB);
        readingStrategy.open(file);
    }

    private ReadingStrategy createReadingStrategy(long fileSize, int allAtOnceSizeLimit_MB) {
        long allAtOnceSizeLimit_BYTES = allAtOnceSizeLimit_MB * MEGABYTE;

        boolean verbose = "true".equals(System.getProperty("triangle.verbose"));
        if (verbose) {
            int fileSizeMB = (int) (fileSize / MEGABYTE);
            if (fileSizeMB == 0) {
                System.out.print("File size is < 1 mb and ");
            } else {
                System.out.format("File size is %,d mb and ", fileSizeMB);
            }
            System.out.format("\"all at once\" size limit is %,d mb.%n", allAtOnceSizeLimit_MB);
            System.out.print("\"All at once\" size limit ");
        }

        if (fileSize < allAtOnceSizeLimit_BYTES) {
            readingAllAtOnce = true;
            if (verbose) {
                System.out.println("not exceeded. Reading file all at once.");
            }
            return new AllAtOnceReadingStrategy();

        } else {
            readingAllAtOnce = false;
            if (verbose) {
                System.out.println(" exceeded. Reading file piece by piece.");
            }
            return new PieceByPieceReadingStrategy();
        }
    }

    public boolean isReadingAllAtOnce() {
        return readingAllAtOnce;
    }

    public String readLine() {
        return readingStrategy.readPreviousLine();
    }

    public void close() {
        readingStrategy.close();
    }
}
